#include <math.h>
#include <string>
#include "Camera.h"

using namespace core;
using namespace cmn;

const float Camera::Speed = 5.0f;

Camera::Camera() :
	m_pos( Transform::Zero() ),
	m_vel( Transform::Zero() ),
	m_scale( 1.0f ),
	m_velFactor( 0.1f ),
	m_scaleFactor( 1.0f )
{}

Camera::Camera( const Transform& pos, const Transform& vel, float scale ) :
	m_pos( pos ),
	m_vel( vel ),
	m_scale( scale ),
	m_velFactor( 0.1f ),
	m_scaleFactor( 1.0f )
{}

Camera::Camera( const Camera& camera ) :
	m_pos( camera.GetPos() ),
	m_vel( camera.GetVel() ),
	m_scale( camera.GetScale() ),
	m_velFactor( camera.m_velFactor ),
	m_scaleFactor( camera.m_scaleFactor )
{}

Camera::~Camera()
{}

Vec2 Camera::GetAcceleration() {
	float speed = m_vel.Vec.Length();
	if( speed > Speed / m_scale )
		return Vec2::Zero();

	Vec2 acceleration = Vec2::Zero();

	if( core::Keyboard::IsKeyPressed( KeyboardKey::Left ) )
		acceleration += Vec2::Left() * Speed / m_scale;

	if( core::Keyboard::IsKeyPressed( KeyboardKey::Right ) )
		acceleration += Vec2::Right() * Speed / m_scale;

	if( core::Keyboard::IsKeyPressed( KeyboardKey::Up ) )
		acceleration += Vec2::Up() * Speed / m_scale;

	if( core::Keyboard::IsKeyPressed( KeyboardKey::Down ) )
		acceleration += Vec2::Down() * Speed / m_scale;

	return acceleration;
}

void Camera::Update( float dt ) {
	Vec2 acc = GetAcceleration();

	m_vel.Vec += acc * dt;
	m_vel *= powf( m_velFactor, dt );

	float speed = m_vel.Vec.Length();
	if( speed < 0.00001f * Speed / m_scale )
		m_vel.Vec = Vec2::Zero();

	m_pos += m_vel * dt;
	m_scale *= powf( m_scaleFactor, dt );
}

void Camera::KeyPressed( KeyboardKey key ) {
	float scaleFactor = m_scaleFactor;

	switch( key ) {
		case KeyboardKey::KpAdd:
			m_scaleFactor = scaleFactor + 0.1f * Speed;
			return;
		case KeyboardKey::KpSubtract:
			m_scaleFactor = scaleFactor - 0.1f * Speed;
			return;
		default:
			return;
	}
}

void Camera::KeyReleased( KeyboardKey key ) {
	float scaleFactor = m_scaleFactor;

	switch( key ) {
		case KeyboardKey::KpAdd:
			m_scaleFactor = scaleFactor - 0.1f * Speed;
			return;
		case KeyboardKey::KpSubtract:
			m_scaleFactor = scaleFactor + 0.1f * Speed;
			return;
		default:
			return;
	}
}
